#include "downloadmanager.h"

#include <e32base.h>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QUrl>
#include <QStringList>
#include <QVariant>
#include <QDebug>

//TODO: replace KHostName value with your host URL
#define KHostName "http://www.izinin.fn-sandbox.net"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// PTV server API definition see http://projects.developer.nokia.com/iap_sample/wiki
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define KCmdGetProductList "/mobile_getproductlist.php"
#define KCmdGetProductURL "/mobile_getproducturl.php"
#define KAccountFieldName "accountdigest"
#define KProductIdFieldName "productid"
#define KProductTicketFieldName "ticket"
// predefined server response
#define KHaveToBuyResponse     "HAVE2BUY"

// common request related literals definition
#define KmanagerLineBreak "</br>"
#define KFieldDelimiter "&"

DownloadManager::DownloadManager(QObject* parent):
    QObject(parent),
    state(State_IDLE)
{
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));
}

int DownloadManager::getProductList(QStringList& products)
{
    if(state != State_IDLE){
        qDebug() << "DownloadManager is busy, getProductList rejected";
        return KErrInUse;
    }

    state = State_GETPRODUCTLIST;
    productList = &products;
    productList->clear();

    QNetworkRequest request;
    request.setUrl(QUrl(KHostName KCmdGetProductList));

    QNetworkReply *reply = manager->get(request);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(replyError(QNetworkReply::NetworkError)));

    return KErrNone;
}

void DownloadManager::replyFinished(QNetworkReply* reply)
{
    QByteArray buf;
    reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(reply->error() != QNetworkReply::NoError){
        qDebug() << "http reply error : " << reply->error();
    }else{
        buf = reply->readAll();
    }

    switch(state){
        case State_GETPRODUCTLIST:
            handleProductList(buf);
            break;
        case State_GETPRODUCT:
            handleProduct(buf);
            break;
        default:
            break;
    }

    state = State_IDLE;
}

void DownloadManager::handleProductList(QByteArray& buf)
{
    QTextStream stream(&buf);
    QString line = stream.readLine();
    while (!line.isNull()){
        line.trimmed();
        if(!line.isEmpty()){
            QStringList elems = line.split(KmanagerLineBreak);
            foreach(QString product, elems){
                if(!product.isEmpty()){
                    productList->append(product.trimmed());
                }
            }
        }
        line = stream.readLine();
    }

    emit productListComplete();
}

void DownloadManager::handleProduct(QByteArray& buf)
{
    emit productComplete(&buf);
}

void DownloadManager::replyError(QNetworkReply::NetworkError error)
{
    qDebug() << "http error : " << error;
}

int DownloadManager::getProduct(QString account,
                                QString productId, QString* ticket)
{
    if(state != State_IDLE){
        qDebug() << "DownloadManager is busy, getProduct rejected";
        return KErrInUse;
    }

    qDebug() << "PTV server getProduct : " << "account digest "
             << account << "product ID" << productId;

    state = State_GETPRODUCT;

    QNetworkRequest request;
    request.setUrl(QUrl(KHostName KCmdGetProductURL));

    QByteArray postData;
    postData.append(KAccountFieldName "=");
    //NOTE "+" character that may be in base64 string
    // stands for space symbol in the POST data encoding scheme
    postData.append(QUrl::toPercentEncoding(account, "", "+"));
    postData.append(KFieldDelimiter);
    postData.append(KProductIdFieldName "=");
    postData.append(productId);

    if(ticket){
        postData.append(KFieldDelimiter);
        postData.append(KProductTicketFieldName "=");
        postData.append(QUrl::toPercentEncoding(*ticket, "", "+"));
    }

    QNetworkReply *reply = manager->post(request, postData);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(replyError(QNetworkReply::NetworkError)));

    return KErrNone;
}
// NOTE: this function is only
// for having PTV server API definition in one place, this module
bool DownloadManager::isNeedToBuy(QByteArray& response)
{
    return (response == KHaveToBuyResponse);
}
